
__DefBitFieldType SHFLMode<2>
    IDX;
    UP;
    DOWN;
    BFLY;

__DefBitFieldType VOTEOp<2>
    ANY;
    ALL;
    EQ;

__DefBitFieldType MATCHOp<1>
    ANY;
    ALL;

__DefBitFieldType MATCHDType<1>
    U32;
    U64;

__DefBitFieldType REDUXOp<3>
    AND;
    OR;
    XOR;

    SUM;
    MAX;
    MIN;

__DefBitFieldType REDUXDType<2>
    U32;
    S32;
    //F32???

// Sync Op
__DefGroup SYNCOp : [ALL]
  __Encoding
    field<12, 3> Pred pg = PT;
    field<15, 1> PModi pg.not = False;

__DefOptype SHFL : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==SHFL;

    field<16, 8> Reg rd;
    field<24, 8> Reg ra;

    field<80, 2> SHFLMode mode;
    field<106,3> Pred pu;
  
  __Syntax
```asm          
SHFL.mode pu, Rd, Ra, SrcB, SrcC      $sched $req $wsb ;

.mode = {.IDX, .UP, .DOWN, .BFLY}
```

  __Description
在同一个warp的参与线程之间进行GPR值的交换：
- 每个参与线程试图获取另一个参与线程的某个GPR值
- 如果获取成功，则输出对应的GPR值，并返回一个为true的谓词
- 否则返回的谓词为false

注意：如果试图获取另一个inactive线程的GPR值，结果是未定义的。

更具体的语义请参考__Semantics部分。

  __OperandInfo
输出操作数Rd和输入操作数Ra都必须是GPR，分别表示交换的GPR结果和来源。

输入SrcB和SrcC用于指定发生GPR交换的线程对（thread pair），合法的来源组合包括：
| SrcB | SrcC |
|:----|:----|
| GPR | GPR |
| GPR | UImm13 |
| UImm5 | GPR |
| UImm5 | UImm13 |

只有SrcC的低5bit和高5bit是有效的。

输出谓词pu必须是PR，表示交换是否成功。

  __ModifierInfo
.mode修饰符的可取值包括.IDX、.UP、.DOWN和.BFLY。

.mode各个取值的含义请参考Semantics部分。

  __Semantics
```asm
SHFL.mode pu, Rd, Ra, SrcB, SrcC:
    // 获取当前thread的lane ID（5bit）
    lane[4:0]  = [Thread].laneid;
    // SrcB（5bit）用于计算参与交换的源GPR所在的lane ID
    bval[4:0] = b[4:0];
    // 获取SrcC的低5bit和高5bit
    cval[4:0] = c[4:0];
    segmask[4:0] = c[12:8];

    // 假设收集所有参与线程的源GPR值至一个数组SourceA中：
    SourceA[lane] = Ra;
    
    // 将warp内的32线程进行分组，当前线程所在的线程组的起止范围是：
    // [minLane, maxLane]
    maxLane = (lane[4:0] & segmask[4:0]) | (cval[4:0] & ~segmask[4:0]);
    minLane = (lane[4:0] & segmask[4:0]);

    // 根据.mode决定与当前线程交换的源GPR所在线程lane ID：
    // 根据lane ID和[minLane, maxLane]判断交换是否合法
    // 注：不同的.mode对合法性的判定不同
    switch (.mode) {
        case .UP:    j = lane - bval; pu = (j >= maxLane); break;
        case .DOWN:  j = lane + bval; pu = (j <= maxLane); break;
        case .BFLY:  j = lane ^ bval; pu = (j <= maxLane); break;
        case .IDX:   j = minLane  | (bval[4:0] & ~segmask[4:0]);
                     pu = (j <= maxLane); break;
    }
    // 如果pu为false，说明交换不合法，将自己的Ra值拷贝给Rd输出
    if (!pu) 
        j = lane;
    // 否则，将目标线程的Ra值拷贝给Rd输出
    Rd = SourceA[j];
```

  __Examples
```asm
SHFL.UP pu, R1, R0, 0x1, 0x0 ;
```

__DefOpcode SHFL_RRR : [SHFL]
  __Encoding
    field<8,  4> SType stype==RRR;
    field<32, 8> Reg rb;
    field<64, 8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, rb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode SHFL_RRI : [SHFL]
  __Encoding
    field<8,  4> SType stype==RRI;
    field<32, 8> Reg rb;
    field<40,13> UImm13 vc;
  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, rb, vc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 13;

__DefOpcode SHFL_RIR : [SHFL]
  __Encoding
    field<8,  4> SType stype==RIR;
    field<53, 5> UImm5 vb;
    field<64, 8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, vb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 5;
    Bitwidth<rc> = 32;

__DefOpcode SHFL_RI : [SHFL]
  __Encoding
    field<8,  4> SType stype==RI;

    field<40,13> UImm13 vc;
    field<53, 5> UImm5 vb;
  __OperandInfo
    InList<pg, ra, vb, vc>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, vb, vc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> =  5;
    Bitwidth<vc> = 13;

__DefOptype MOVM : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==MOVM;
    field<16, 8> Reg rd;

__DefOpcode MOVM_R : [MOVM]
  __Encoding
    field<8,  4> SType stype==R;
    field<24, 8> Reg ra;
  __OperandInfo
    InList<pg, ra>;
    OutList<rd>;
    Order<pg, rd, ra>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;

__DefOptype VOTE : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==VOTE;

    field<80, 2> VOTEOp voteop;
    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not=False;

    field<106, 3> Pred pu;

  __Syntax
```asm          
VOTE.voteop Rd, pu, {!}pp      $sched $req ;

.voteop = {.ANY, .ALL, .EQ}
```

  __Description
VOTE用于对参与线程的输入谓词进行统计，生成统计结果。

只有pg = true的active线程会参与VOTE的统计。

更具体的语义请参考Semantics部分。

  __OperandInfo
输出操作数Rd必须来源于GPR。

输出谓词pu和输入谓词pp必须来源于PR。

其中pp可以带有一个逻辑取反前缀（!）作为修饰符，表示对来源取反作为输入。

  __ModifierInfo
.voteop的可取值包括.ANY、.ALL和.EQ：
| .voteop | 含义 |
|:------|:-----|
| .ANY | pu = 所有参与线程的输入谓词的逻辑或结果 |
| .ALL | pu = 所有参与线程的输入谓词的逻辑与结果 |
| .EQ  | 当且仅当所有参与线程的输入谓词相等时，pu = true，否则pu = false |

  __Semantics
用自然语言描述VOTE的语义：
- 确定当前warp中参与VOTE的线程集合S：所有active且pg=true的线程
- 确定所有参与线程的输入谓词值（考虑输入的逻辑取反修饰符）
- 根据.voteop值确定输出谓词pu：
    - .ANY：pu = 所有参与线程输入谓词值的逻辑或
    - .ALL：pu = 所有参与线程输入谓词值的逻辑与
    - .EQ ：
        - 如果所有参与线程输入谓词值相同，pu = true
        - 否则，pu = false
- 确定输出Rd的值：
    - 将Rd初始化为0x00000000
    - 对每个参与线程，如果输入谓词值为true，将Rd的对应位置为1

  __Examples
```asm
VOTE.EQ R0, P0, PT ; 
```

__DefOpcode VOTE_X : [VOTE]
  __Encoding
    field<8,  4> SType stype==X;
    field<16, 8> Reg rd;
  __OperandInfo
    InList<pg, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, pp>;
    Bitwidth<rd> = 32;

__DefOptype VOTEU : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==VOTEU;

    field<80, 2> VOTEOp voteop;
    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not=False;

    field<106, 3> UPred upu;

  __Syntax
```asm          
VOTEU.voteop URd, upu, {!}pp      $sched $req ;

.voteop = {.ANY, .ALL, .EQ}
```

  __Description
VOTEU用于对参与线程的输入谓词进行统计，生成统计结果。

只有pg = true的active线程会参与VOTEU的统计。

更具体的语义请参考Semantics部分。

  __OperandInfo
输出操作数URd必须来源于UR。

输出谓词upu必须来源于UPR。

输入谓词pp必须来源于PR。

pp可以带有一个逻辑取反前缀（!）作为修饰符，表示对来源取反作为输入。

  __ModifierInfo
.voteop的可取值包括.ANY、.ALL和.EQ：
| .voteop | 含义 |
|:------|:-----|
| .ANY | upu = 所有参与线程的输入谓词的逻辑或结果 |
| .ALL | upu = 所有参与线程的输入谓词的逻辑与结果 |
| .EQ  | 当且仅当所有参与线程的输入谓词相等时，upu = true，否则upu = false |

  __Semantics
用自然语言描述VOTEU的语义：
- 确定当前warp中参与VOTEU的线程集合S：所有active且pg=true的线程
- 确定所有参与线程的输入谓词值（考虑输入的逻辑取反修饰符）
- 根据.voteop值确定输出谓词upu：
    - .ANY：upu = 所有参与线程输入谓词值的逻辑或
    - .ALL：upu = 所有参与线程输入谓词值的逻辑与
    - .EQ ：
        - 如果所有参与线程输入谓词值相同，upu = true
        - 否则，upu = false
- 确定输出URd的值：
    - 将URd初始化为0x00000000
    - 对每个参与线程，如果输入谓词值为true，将URd的对应位置为1

  __Examples
```asm
VOTEU.EQ UR0, UP0, PT ; 
```

__DefOpcode VOTEU_X : [VOTEU]
  __Encoding
    field<8,  4> SType stype==X;
    field<16, 6> UReg urd;
  __OperandInfo
    InList<pg, pp>;
    OutList<urd, upu>;
    Order<pg, urd, upu, pp>;
    Bitwidth<urd> = 32;

__DefOptype REDUX : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==REDUX;

    field<16, 8> Reg rd;

    field<80, 3> REDUXOp reduxop;
    field<83, 2> REDUXDType dtype=U32;

  __Syntax
```asm          
REDUX{.dtype}.reduxop Rd, Ra      $sched $req $wsb ;

.dtype = {.U32*, .S32}
.reduxop = {.AND, .OR, .XOR, .SUM, .MAX, .MIN}
```

  __Description
REDUX用于对参与线程的GPR输入进行归约，每个参与线程都能获得归约结果。

只有pg = true的active线程会参与REDUX的归约计算。

  __OperandInfo
输出Rd和输入Ra都必须来源于GPR。

  __ModifierInfo
.dtype的可取值包括.U32（默认值）和.S32，分别表示将参与归约的输入视为UINT32或INT32。

.dtype仅在进行.SUM、.MIN或.MAX归约时有效，在其他模式下，输入总是被视为32bit无符号数。

.reduxop用于指定归约计算的类型：
| .reduxop | 含义 |
|:------|:-----|
| .AND | 对所有参与线程的输入进行按位与 |
| .OR  | 对所有参与线程的输入进行按位或 |
| .XOR | 对所有参与线程的输入进行按位异或 |
| .SUM | 对所有参与线程的输入进行累加 |
| .MAX | 求所有参与线程的输入最大值 |
| .MIN | 求所有参与线程的输入最小值 |

注意：进行.SUM归约计算时，如果结果超出32位整数的表达范围，则仅保留结果的低32位输出到Rd寄存器，不做其他特殊处理。

  __Semantics
用自然语言描述REDUX的语义：
- 确定当前warp中参与VOTE的线程集合S：所有active且pg=true的线程
- 根据.reduxop确定归约方式：
    - .AND：Rd = 所有参与线程输入Ra的按位与
    - .OR ：Rd = 所有参与线程输入Ra的按位或
    - .XOR：Rd = 所有参与线程输入Ra的按位异或
    - .SUM：
        - d = 所有参与线程输入Ra的求和
        - 如果d溢出了.type的表示范围，将d截断到32bit输出到Rd
    - .MAX：Rd = 所有参与线程输入Ra的最大值
    - .MIN：Rd = 所有参与线程输入Ra的最小值

  __Examples
```asm
REDUX.SUM R0, R1 ; 
```

__DefOpcode REDUX_R : [REDUX]
  __Encoding
    field<8,  4> SType stype==R;
    field<24, 8> Reg ra;
  __OperandInfo
    InList<pg, ra>;
    OutList<rd>;
    Order<pg, rd, ra>;
    Bitwidth<ra> = 32;
    Bitwidth<rd> = 32;

__DefOptype REDUXU : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==REDUXU;

    field<16, 6> UReg urd;

    field<80, 3> REDUXOp reduxop;
    field<83, 2> REDUXDType dtype=U32;

  __Syntax
```asm          
REDUXU{.dtype}.reduxop URd, Ra      $sched $req $wsb ;

.dtype = {.U32*, .S32}
.reduxop = {.AND, .OR, .XOR, .SUM, .MAX, .MIN}
```

  __Description
REDUXU用于对参与线程的GPR输入进行归约，归约结果写入UR。

只有pg = true的active线程会参与REDUXU的归约计算。

  __OperandInfo
输出URd必须是UR。

输入Ra必须来源于GPR。

  __ModifierInfo
.dtype的可取值包括.U32（默认值）和.S32，分别表示将参与归约的输入视为UINT32或INT32。

.dtype仅在进行.SUM、.MIN或.MAX归约时有效，在其他模式下，输入总是被视为32bit无符号数。

.reduxop用于指定归约计算的类型：
| .reduxop | 含义 |
|:------|:-----|
| .AND | 对所有参与线程的输入进行按位与 |
| .OR  | 对所有参与线程的输入进行按位或 |
| .XOR | 对所有参与线程的输入进行按位异或 |
| .SUM | 对所有参与线程的输入进行累加 |
| .MAX | 求所有参与线程的输入最大值 |
| .MIN | 求所有参与线程的输入最小值 |

注意：进行.SUM归约计算时，如果结果超出32位整数的表达范围，则仅保留结果的低32位输出到URd寄存器，不做其他特殊处理。

  __Examples
用自然语言描述REDUXU的语义：
- 确定当前warp中参与VOTE的线程集合S：所有active且pg=true的线程
- 根据.op确定归约方式：
    - .AND：URd = 所有参与线程输入Ra的按位与
    - .OR ：URd = 所有参与线程输入Ra的按位或
    - .XOR：URd = 所有参与线程输入Ra的按位异或
    - .SUM：
        - d = 所有参与线程输入Ra的求和
        - 如果d溢出了.type的表示范围，将d截断到32bit输出到URd
    - .MAX：URd = 所有参与线程输入Ra的最大值
    - .MIN：URd = 所有参与线程输入Ra的最小值

__DefOpcode REDUXU_R : [REDUXU]
  __Encoding
    field<8,  4> SType stype==R;
    field<24, 8> Reg ra;
  __OperandInfo
    InList<pg, ra>;
    OutList<urd>;
    Order<pg, urd, ra>;
    Bitwidth<ra> = 32;
    Bitwidth<urd> = 32;

__DefOptype MATCH : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==MATCH;

    field<16, 8> Reg rd;
    field<80, 1> MATCHOp matchop;
    field<81, 1> MATCHDType dtype=U32;

    field<106, 3> Pred pu;

  __Syntax
```asm          
MATCH{.dtype}.matchop Rd, pu, Ra      $sched $req $wsb ;

.dtype = {.U32*, .U64}
.matchop = {.ANY, .ALL}
```

  __Description
MATCH用于对参与线程的GPR输入进行比较，每个参与线程都能获得比较的结果。

只有pg = true的active线程会参与比较。

  __OperandInfo
输出Rd和输入Ra都必须来源于GPR。

其中Rd是32bit寄存器，Ra可以是32bit，也可以是64bit，取决于.dtype修饰符。

输出谓词pu必须来源于UPR。

  __ModifierInfo
.dtype的可取值包括.U32（默认值）和.U64，分别表示输入寄存器Ra是32bit还是64bit位宽。

.matchop用于指定比较的方式：
| .matchop | 含义 |
|:------|:-----|
| .ANY | 输出输入与当前线程输入相等的参与线程的mask |
| .ALL | 当且仅当所有参与线程的输入相等时，输出参与线程的mask，否则输出0 |

  __Semantics
用自然语言描述MATCH的语义：
- 确定当前warp中参与VOTE的线程集合S：所有active且pg=true的线程
- 初始化输出Rd = 0，pu = false
- 根据.matchop确定比较方式：
    - .ANY：
        - 获取当前线程的输入Ra的值：a = Ra
        - 判断S中所有线程的Ra是否与a相等：
            - 如果相等，将Rd中的对应bit置为1
            - 如果不等，保持Rd中对应bit为0
    - .ALL：
        - 判断S中所有线程的Ra是否相同：
            - 如果相同，将Rd与S中所有线程相对应的bit置为1，pu = true
            - 如果不同，则保持Rd = 0，pu = false不变

  __Examples
```asm
MATCH.ANY     R0, P0, R1     ; 
MATCH.U64.ALL R0, P0, R[2:3] ;
```

__DefOpcode MATCH_R : [MATCH]
  __Encoding
    field<8,  4> SType stype==R;

    field<24, 8> Reg ra;
  __OperandInfo
    InList<pg, ra>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra>;
    Bitwidth<ra> = 32 + (dtype=="U64")*32;
    Bitwidth<rd> = 32;

__DefOptype ELECTU : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==ELECTU;
    field<16, 6> UReg urd;
    field<106, 3> Pred pu;

__DefOpcode ELECTU_X : [ELECTU]
  __Encoding
    field<8,  4> SType stype==X;
    field<98, 3> Pred pp=PT;
    field<101, 1> PModi pp.not=False;
  __OperandInfo
    InList<pg, pp>;
    OutList<urd, pu>;
    Order<pg, pu, urd, pp>;
    Bitwidth<urd> = 32;

__DefOpcode ELECTU_U : [ELECTU]
  __Encoding
    field<8,  4> SType stype==U;
    field<32, 6> UReg urb;
    field<97, 1> SignModi urb.bitnot = False;
  __OperandInfo
    InList<pg, urb>;
    OutList<urd, pu>;
    Order<pg, pu, urd, urb>;
    Bitwidth<urb> = 32;
    Bitwidth<urd> = 32;

__DefOptype ELECT : [SYNCOp]
  __Encoding
    field<0,  8> Optype optype==ELECT;
    field<16, 8> Reg rd;
    field<106, 3> Pred pu;

__DefOpcode ELECT_X : [ELECT]
  __Encoding
    field<8,  4> SType stype==X;
    field<98, 3> Pred pp=PT;
    field<101, 1> PModi pp.not=False;
  __OperandInfo
    InList<pg, pp>;
    OutList<rd, pu>;
    Order<pg, pu, rd, pp>;
    Bitwidth<rd> = 32;

__DefOpcode ELECT_U : [ELECT]
  __Encoding
    field<8,  4> SType stype==U;

    field<32, 6> UReg urb;
    field<97, 1> SignModi urb.bitnot = False;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd, pu>;
    Order<pg, pu, rd, urb>;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;